package iserver

import (
	"src/zeus/common"
	"src/zeus/linmath"
)

// ICoordEntity 坐标结点
type ICoordEntity interface {
	// AOI是否准备好
	IsAOIReady() bool
	common.Keyer
	GetID() uint64
	//修改自己的坐标，调用SetCoordPos
	SetPos(pos linmath.Vector3)
	// 检查并调用Link对象的SetCoordPos
	SetCoordPos(pos linmath.Vector3)
	GetPos() linmath.Vector3
	SetRota(rota int32)
	GetRota() int32
	// 扫描的时候需要考虑boss有半径，扫描的时候放大半径尺寸
	GetModelRadius() float32

	GetRealPtr() interface{}
	// 是否需要隐身
	SetNeedHide(hide bool)
	GetNeedHide() bool
	// 是否隐身（从坐标格中去掉）
	SetHide(hide bool)
	GetHide() bool
	// 是否对玩家隐藏
	GetPlayerHide() bool
	// 隐藏别人 针对我(记录在我这边)
	SetHideOthersToMe(v bool)
	// 隐藏自己 针对别人(记录在我这边)
	SetHideMeToOthers(v bool)

	// 获取AOI系统中需要知道的主人ID
	GetAOIOwnerUID() uint64

	GetAOILayerIndex() uint8
	SetAOILayerIndex(i uint8)
	// 为真，所有层级都会存在，并触发进入/离开AOI事件;
	//为假,只会在自己做在的层级存在，且不会触发进入/离开AOI事件
	IsAOITrigger() bool
	// 是否为观察者
	IsWatcher() bool
	// 在不在对方的AOI内
	ExistsAOIWeather(o ICoordEntity) bool
	/*
	   链接与被链接的逻辑，没有验证过
	*/
	LinkToTarget(ICoordEntity)
	LinkedBy(ICoordEntity)
	Unlink()
	UnlinkedBy(ICoordEntity)
	GetLinkedEntity() map[uint64]ICoordEntity
	IsLinked() bool
	IsBeLinked() bool
}

// IAOITriggerEntity 拥有AOITrigger能力的Entity
type IAOITriggerEntity interface {
	// e进入我的AOI
	OnEntityEnterAOI(e ICoordEntity)
	// e进入我的AOI之后
	OnAfterEntityEnterAOI(e ICoordEntity)
	// e离开我的AOI
	OnEntityLeaveAOI(e ICoordEntity)
}

// ICoord 座标系统
type ICoord interface {
	SetAnchor(linmath.Vector3)
	//刷新对象的显示逻辑
	RefreshShow(ICoordEntity)
	UpdateCoord(ICoordEntity)
	RemoveFromCoord(ICoordEntity)
	TravsalAOI(ICoordEntity, func(ICoordEntity) bool)
	// 遍历AOI范围内的 所有单位
	TravsalAOINoCheck(n ICoordEntity, cb func(ICoordEntity) bool)

	// 遍历center为中心，半径范围radius内的所有实体执行cb
	TravsalRange(center *linmath.Vector3, radius int, cb func(ICoordEntity) bool)

	// 遍历center为中心，半径范围radius,角度为angle,朝向为rota的扇形内所有实体执行cb
	TravsalSector(center *linmath.Vector3, radius int, rota int32, angle int32, cb func(ICoordEntity) bool)
	// 遍历center为中心，长宽为 length,width,朝向为rota的矩形内所有实体执行cb
	TravsalSquare(center *linmath.Vector3, length, width int, rota int32, cb func(ICoordEntity) bool)
	// 遍历center所在的Tower，在该Tower内的center为中心，半径范围radius内的所有实体执行cb
	TravsalCenter(center *linmath.Vector3, radius int, cb func(ICoordEntity) bool)
	// 遍历center为中心，已radius为半径的圆去掉已innerRadius为圆的面积
	TravsalRing(center *linmath.Vector3, radius, innerradius int, cb func(ICoordEntity) bool)
	// 遍历center为中心，已radius为半径的圆去掉已innerRadius为圆的面积，选取朝向rota，角度为angle的扇环面积
	TravsalSectorRing(center *linmath.Vector3, radius, innerradius int, rota, angle int32, cb func(ICoordEntity) bool)

	// 遍历center为中心，半径范围radius内的所有实体执行cb
	TravsalRangeNocheckModelRadius(center *linmath.Vector3, radius int, cb func(ICoordEntity) bool)
	// 遍历center为中心，半径范围radius,角度为angle,朝向为rota的扇形内所有实体执行cb
	TravsalSectorNocheckModelRadius(center *linmath.Vector3, radius int, rota int32, angle int32, cb func(ICoordEntity) bool)
	// 遍历center为中心，长宽为 length,width,朝向为rota的矩形内所有实体执行cb
	TravsalSquareNocheckModelRadius(center *linmath.Vector3, length, width int, rota int32, cb func(ICoordEntity) bool)

	//获得范围内所有格子ID
	GetTowerIDInRect(rect *common.Rect) []int
	//按ID遍历
	TraversalByTowerID(rect *common.Rect, towerIDs []int, cb func(ICoordEntity) bool)
}
